{"componentChunkName":"component---src-templates-post-js","path":"/simply-learn-full-stack-7","result":{"data":{"site":{"siteMetadata":{"title":"neohed","description":"Blog posts on web development and related areas","author":{"name":"neohed"},"keywords":["Web Development","JavaScript"]}},"mdx":{"frontmatter":{"title":"simply learn-full-stack-7","description":"Full-stack Adding a Database using Prisma to a Node.js app","date":"November 21, 2022","author":null,"banner":null,"slug":"simply-learn-full-stack-7","keywords":null},"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"slug\": \"simply-learn-full-stack-7\",\n  \"date\": \"2022-11-21T11:23:41\",\n  \"title\": \"simply learn-full-stack-7\",\n  \"description\": \"Full-stack Adding a Database using Prisma to a Node.js app\",\n  \"published\": true\n};\n\nvar makeShortcode = function makeShortcode(name) {\n  return function MDXDefaultShortcode(props) {\n    console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n    return mdx(\"div\", props);\n  };\n};\n\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"h1\", null, \"Simply Learn Full-Stack React & Node.js\"), mdx(\"p\", null, \"Let's jump right in!\"), mdx(\"p\", null, \"All the edits we need to make are on the server. We're gonna use Prisma ORM and SqlLite DB for convenience.  We need to install these in \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"node-server\")), mdx(\"p\", null, \"Install the Prisma client which express will use to connect to our database:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-shell\"\n  }), \"npm i -S @prisma/client\\n\")), mdx(\"p\", null, \"Next install Prisma, also on the server:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-shell\"\n  }), \"npm i -D prisma\\n\")), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"-D\"), \" is shorthand for \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"--save-dev\"), \". This saves the package under \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"devDependencies\"))), mdx(\"p\", null, \"Under \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"node-server\"), \" create a new folder \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"prisma\")), mdx(\"p\", null, \"In folder \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"prisma\"), \", create a new file \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"schema.prisma\"), \". Set the contents to:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-text\"\n  }), \"datasource db {\\n  provider = \\\"sqlite\\\"\\n  url      = \\\"file:./data.db?connection_limit=1\\\"\\n}\\n\\ngenerator client {\\n  provider = \\\"prisma-client-js\\\"\\n}\\n\\nmodel Note {\\n  id        String @id @default(cuid())\\n  title     String\\n  content   String\\n  authorId  String\\n  lang      String\\n  isLive    Boolean\\n  category  String\\n\\n  createdAt DateTime @default(now())\\n  updatedAt DateTime @updatedAt\\n\\n  author    Author  @relation(fields: [authorId], references: [id], onDelete: Cascade, onUpdate: Cascade)\\n}\\n\\nmodel Author {\\n  id        String @id @default(cuid())\\n  username  String @unique\\n\\n  createdAt DateTime @default(now())\\n  updatedAt DateTime @updatedAt\\n\\n  notes    Note[]\\n}\\n\")), mdx(\"p\", null, \"We have two tables here:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Note\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Author\")), mdx(\"p\", null, \"To generate the SqlLite database file run this command from \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"node-server\"), \" folder:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-shell\"\n  }), \"npx prisma db push\\n\")), mdx(\"p\", null, \"Now to generate the DB entities run:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-shell\"\n  }), \"npx prisma generate\\n\")), mdx(\"p\", null, \"In \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"node-server\"), \" create a new folder: \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"models\"), \". Inside \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"node-server/models\"), \" create 3 new files:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"db.js\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"author.model.js\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"note.model.js\")), mdx(\"p\", null, \"Edit \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"db.js\"), \" to:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const { PrismaClient } = require(\\\"@prisma/client\\\")\\n\\nlet prisma;\\n\\nif (process.env.NODE_ENV === \\\"production\\\") {\\n  prisma = new PrismaClient()\\n} else {\\n  const {__db__} = global;\\n\\n  if (__db__) {\\n    prisma = __db__\\n  } else {\\n    prisma = new PrismaClient({\\n      log: [\\n        {\\n          emit: \\\"event\\\",\\n          level: \\\"query\\\",\\n        },\\n        \\\"info\\\",\\n        \\\"warn\\\",\\n        \\\"error\\\",\\n      ],\\n    });\\n\\n    prisma.$on(\\\"query\\\", ({query, duration}) => {\\n      console.log(`\\\\x1b[36mprisma:query\\\\x1b[0m ${query}`);\\n      console.log(`Took: ${duration}ms`)\\n    });\\n\\n    global.__db__ = prisma\\n  }\\n\\n  prisma.$connect();\\n}\\n\\nmodule.exports = {\\n  prisma\\n}\\n\")), mdx(\"p\", null, \"In development environments, this creates a single prisma instance and stores it as a global and logs SQL queries to the console.\"), mdx(\"p\", null, \"Edit \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"author.model.js\"), \" to:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const { prisma } = require(\\\"./db\\\")\\n\\nasync function getAuthor(id) {\\n  return prisma.author.findUnique({ where: { id } });\\n}\\n\\nasync function getAuthorByName(username) {\\n  return prisma.author.findUnique({ where: { username } });\\n}\\n\\nasync function createAuthor(\\n  author\\n) {\\n  return prisma.author.create({\\n    data: author\\n  });\\n}\\n\\nmodule.exports = {\\n  getAuthor,\\n  getAuthorByName,\\n  createAuthor,\\n}\\n\")), mdx(\"p\", null, \"Edit \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"note.model.js\"), \" to:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const { prisma } = require(\\\"./db\\\")\\n\\nasync function getNotes() {\\n  return prisma.note.findMany();\\n}\\n\\nasync function getNote(id) {\\n  return prisma.note.findUnique({ where: { id } });\\n}\\n\\nasync function createNote(\\n  note\\n) {\\n  return prisma.note.create({\\n    data: note\\n  });\\n}\\n\\nasync function updateNote(\\n  note\\n) {\\n  return prisma.note.update({\\n    data: note,\\n  });\\n}\\n\\nmodule.exports = {\\n  getNotes,\\n  getNote,\\n  createNote,\\n  updateNote,\\n}\\n\")), mdx(\"p\", null, \"That finishes our data access layer. These ORM functions can now be used in our controllers to access data.\"), mdx(\"p\", null, \"First we need to create a script to seed our database. In the \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"prisma\"), \" folder, create a new file \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"seed.js\"), \":\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const { PrismaClient } = require(\\\"@prisma/client\\\")\\nconst prisma = new PrismaClient();\\n\\nasync function seed() {\\n  // Blitz everything!\\n  await prisma.note.deleteMany();\\n  await prisma.author.deleteMany();\\n\\n  const author = await prisma.author.create({\\n    data: {\\n      username: 'neohed'\\n    },\\n  });\\n\\n  await prisma.note.create({\\n    data: {\\n      title: 'A New Note',\\n      content: 'This note is retrieved from the database!',\\n      authorId: author.id,\\n      lang: 'en',\\n      isLive: true,\\n      category: '',\\n    },\\n  });\\n\\n  console.log(`Database has been seeded. \\uD83C\\uDF31`)\\n}\\n\\nseed()\\n  .then(() => {\\n    console.log('Prisma seed function in prisma/seed.js executed!')\\n  })\\n  .catch((e) => {\\n    console.error(e);\\n    process.exit(1)\\n  })\\n  .finally(async () => {\\n    await prisma.$disconnect()\\n  })\\n\")), mdx(\"p\", null, \"Now we need to reference this script from \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"package.json\"), \". Edit \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"package.json\"), \" to this:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-json\"\n  }), \"{\\n  \\\"name\\\": \\\"server\\\",\\n  \\\"version\\\": \\\"1.0.0\\\",\\n  \\\"description\\\": \\\"\\\",\\n  \\\"main\\\": \\\"index.js\\\",\\n  \\\"scripts\\\": {\\n    \\\"start\\\": \\\"node index.js\\\",\\n    \\\"test\\\": \\\"echo \\\\\\\"Error: no test specified\\\\\\\" && exit 1\\\"\\n  },\\n  \\\"keywords\\\": [],\\n  \\\"author\\\": \\\"\\\",\\n  \\\"license\\\": \\\"ISC\\\",\\n  \\\"dependencies\\\": {\\n    \\\"@prisma/client\\\": \\\"^4.0.0\\\",\\n    \\\"body-parser\\\": \\\"^1.20.0\\\",\\n    \\\"cors\\\": \\\"^2.8.5\\\",\\n    \\\"express\\\": \\\"^4.18.1\\\",\\n    \\\"morgan\\\": \\\"^1.10.0\\\"\\n  },\\n  \\\"devDependencies\\\": {\\n    \\\"prisma\\\": \\\"^4.0.0\\\"\\n  },\\n  \\\"prisma\\\": {\\n    \\\"seed\\\": \\\"node prisma/seed.js\\\"\\n  }\\n}\\n\")), mdx(\"p\", null, \"Now run the seed script, execute this:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-shell\"\n  }), \"npx prisma db seed\\n\")), mdx(\"p\", null, \"This will run the \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"seed.js\"), \" script and populate the database with one author and one note record.\"), mdx(\"p\", null, \"And finally, edit \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"note.controller.js\"), \" to:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const authorRepo = require('../models/author.model');\\nconst noteRepo = require('../models/note.model');\\n\\nasync function getNote(req, res) {\\n  const notes = await noteRepo.getNotes();\\n  //HACK return top 1 note\\n  const { authorId, ...noteRest } = notes[0];\\n  const { username } = await authorRepo.getAuthor(authorId);\\n\\n  res.json({ note: {\\n      ...noteRest,\\n      author: username\\n    }\\n  });\\n}\\n\\nasync function postNote(req, res) {\\n  const {body} = req;\\n  const {id, title, content, author, lang, isLive, category} = body;\\n\\n  console.log('Server received data:');\\n  console.log({id, title, content, author, lang, isLive, category})\\n\\n  res\\n    .status(200)\\n    .json({\\n      message: 'Ok'\\n    })\\n}\\n\\nmodule.exports = {\\n  getNote,\\n  postNote\\n}\\n\")), mdx(\"p\", null, \"If you run your server and client now, you should see different data, loaded from the SqlLite database!  You will also see the SQL queries logged in your server console.\"), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/simply-learn-full-stack-8\"\n  }), \"Next CRUD operations\"), \", ...\"), mdx(\"p\", null, \"Code repo: \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/neohed/node-react-stack\"\n  }), \"Github Repository\")));\n}\n;\nMDXContent.isMDXComponent = true;"}},"pageContext":{"id":"eb63bf5d-0384-5318-b1e3-189ac98bb7a8","prev":{"id":"5eaeb00a-836c-577b-964a-d2e946ff9468","parent":{"name":"index","sourceInstanceName":"blog"},"excerpt":"Simply Learn Full-Stack React & Node.js Let's wrap things up. In folder  node-server  edit  note.model.js  to: In folder  node-server  edit  note.controller.js  to: In  node-server  edit  routes/index.js  to: Server side we now have all the…","fields":{"title":"simply learn-full-stack-8","description":"Full-stack tutorial. Creating CRUD operations using Prisma","slug":"simply-learn-full-stack-8","absolutePath":"D:/Workspace/Github/neohed-blog/content/blog/learn-full-stack-simply-08/index.mdx","banner":null,"date":"2022-11-21T11:25:39"}},"next":{"id":"b005ef5d-4ace-5222-b023-d44db83deae2","parent":{"name":"index","sourceInstanceName":"blog"},"excerpt":"Simply Learn Full-Stack React & Node.js Now we're going to  POST  data to our server from the client. Previously we've used HTTP GET requests which are for getting data.  To add data we use HTTP POST. First we need to make a few small changes to our…","fields":{"title":"simply learn-full-stack-6","description":"Full-Stack React & Node.js - HTTP POST","slug":"simply-learn-full-stack-6","absolutePath":"D:/Workspace/Github/neohed-blog/content/blog/learn-full-stack-simply-06/index.mdx","banner":null,"date":"2022-11-21T11:19:35"}}}}}